import logging
from logging.handlers import TimedRotatingFileHandler
from datetime import datetime
import os
from typing import Optional, Callable

class Logger:
    def __init__(self, log_dir: str = "../logs", log_level: str = "INFO", gui_callback: Optional[Callable] = None, module="SYSTEM"):
        """
        日志工具类
        
        :param log_dir: 日志存储目录
        :param log_level: 日志级别（INFO/WARNING/ERROR）
        :param gui_callback: GUI回调函数（用于实时显示日志）
        :param module: 生成日志的模块名
        """
        # 路径安全处理
        self.log_dir = os.path.abspath(log_dir)
        self.log_level = log_level.upper()
        self._validate_log_level()
        
        self.gui_callback = gui_callback
        self.default_module = module
        self._setup_logging()
        
    def setModule(self, module: str):
        """设置当前模块名称"""
        self.default_module = module

    def _validate_log_level(self):
        """校验日志级别合法性"""
        valid_levels = {"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"}
        if self.log_level not in valid_levels:
            raise ValueError(f"Invalid log level: {self.log_level}")

    def _setup_logging(self):
        """初始化日志配置"""
        # 确保日志目录存在
        os.makedirs(self.log_dir, exist_ok=True)
        # 创建Logger实例
        self.logger = logging.getLogger("Logger")
        # self.logger = logging.getLogger(f"{self.default_module}_Logger")
        self.logger.setLevel(self.log_level)

        # 清除已有处理器
        self.logger.handlers.clear()

        # 文件处理器（显式设置级别）
        log_file = os.path.join(self.log_dir, "system.log")
        file_handler = TimedRotatingFileHandler(
            log_file, when='midnight', backupCount=7, encoding='utf-8'
        )
        file_handler.setLevel(self.log_level)
        file_handler.setFormatter(self._get_formatter())

        # 控制台处理器（显式设置级别）
        console_handler = logging.StreamHandler()
        console_handler.setLevel(self.log_level)
        console_handler.setFormatter(self._get_formatter())

        self.logger.addHandler(file_handler)
        self.logger.addHandler(console_handler)

    def _get_formatter(self) -> logging.Formatter:
        return logging.Formatter(
            "[%(asctime)s] [%(levelname)s] [%(custom_module)s] %(message)s",
            datefmt="%Y-%m-%d %H:%M:%S"
        )

    def log(self, level: str, message: str, module: str = None):
        """
        记录日志并触发GUI回调
        """
        # 日志级别校验
        valid_levels = {"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"}
        level = level.upper()
        if level not in valid_levels:
            raise ValueError(f"Invalid log level: {level}")
            
        module = module or self.default_module
        log_method = getattr(self.logger, level.lower())
        
        try:
            log_method(message, extra={'custom_module': module})
        except Exception as e:
            # 记录到文件（如果文件处理器可用）
            if self.logger.handlers:
                self.logger.error(f"内部日志错误: {str(e)}")
        if self.gui_callback:
            try:
                self.gui_callback({
                    "time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                    "level": level,
                    "custom_module": module,
                    "message": message
                })
            except Exception as e:
                self.logger.error(f"GUI callback error: {str(e)}")
            
    def export_logs(self, export_format: str = 'csv'):
        """导出日志到文件"""
        log_file = os.path.join(self.log_dir, "system.log")
        if not os.path.exists(log_file):
            return False
        
        try:
            with open(log_file, 'r', encoding='utf-8') as f:
                logs = [line.strip() for line in f.readlines()]
            
            if export_format == 'csv':
                output_file = os.path.join(self.log_dir, f"export_{datetime.now().strftime('%Y%m%d%H%M')}.csv")
                with open(output_file, 'w', encoding='utf-8') as f:
                    f.write("timestamp,level,module,message\n")
                    for log in logs:
                        parts = log.split('] ')
                        if len(parts) >= 4:
                            timestamp = parts[0].strip('[')
                            level = parts[1].strip('[')
                            module = parts[2].strip('[')
                            message = '] '.join(parts[3:])
                            f.write(f"{timestamp},{level},{module},{message}\n")
                return True
        except Exception as e:
            self.logger.error(f"日志导出失败: {str(e)}")
            return False

    # 快捷记录日志方法
    def info(self, message: str, module: str = None):
        self.log("INFO", message, module)

    def warning(self, message: str, module: str = None):
        self.log("WARNING", message, module)

    def error(self, message: str, module: str = None):
        self.log("ERROR", message, module)